﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YRevitJig;
using YJKGeometryFuncs;
using YJKPresentation.Utils;

namespace YJKRevitDimension.DetailIndex.Jig
{
	public class DetailIndexJig : XUiJigBase
	{
		public DetailIndexJig(UIDocument uiDoc) : base(uiDoc)
		{
			this.JigStage = DetailIndexJig.EStage.eNoOper;
		}

		public DetailIndexJig(UIDocument uiDoc, bool ifUseCustomerAngle = false, double angle = 0.0) : base(uiDoc)
		{
			this.JigStage = DetailIndexJig.EStage.eNoOper;
			this.IfUseCustomerAngle = ifUseCustomerAngle;
			this.Angle = angle;
		}

		public XYZ CenterPoint { get; set; }

		public XYZ OnCurvePoint { get; set; }

		public DetailIndexJig.EStage JigStage { get; set; }

		public XYZ PickCenterPoint(string strPrompt = "请确定圆中心点:")
		{
			XYZ centerPoint;
			try
			{
				this.JigStage = DetailIndexJig.EStage.eCenterPt;
				this.CenterPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				centerPoint = this.CenterPoint;
			}
			catch
			{
				this.CenterPoint = null;
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				throw;
			}
			return centerPoint;
		}

		public double PickRadis(XYZ ptCenter, ref XYZ onCirclPoint, string strPrompt = "请确定圆上一点：")
		{
			try
			{
				this.JigStage = DetailIndexJig.EStage.eOnCurve;
				this.CenterPoint = ptCenter;
				onCirclPoint = base.UiDoc.Selection.PickPoint(strPrompt);
			}
			catch
			{
				if (this.m_prompDlg != null && base.CmdEndType == XUiJigBase.ECmdEndType.eEnter)
				{
					base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
					XYZ xyz = base.Client2Revit(this.m_ptCur);
					double num = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
					XYZ xyz2 = (xyz - this.CenterPoint).Normalize();
					this.OnCurvePoint = this.CenterPoint + xyz2 * num;
					throw;
				}
				this.OnCurvePoint = null;
				return 0.0;
			}
			this.JigStage = DetailIndexJig.EStage.eNoOper;
			return this.CenterPoint.DistanceTo(onCirclPoint);
		}

		public XYZ StartPoint { get; set; }

		public XYZ EndPoint { get; set; }

		public double Angle { get; set; }

		public bool IfUseCustomerAngle { get; set; }

		public XUiJigBase.EResetPoint ResetPoint { get; set; }

		public DetailIndexJig.Step ThisOperStep { get; set; }

		public XYZ PickStartPoint(string strPrompt = "请确定直线起点：")
		{
			XYZ startPoint;
			try
			{
				this.JigStage = DetailIndexJig.EStage.eStartPt;
				this.StartPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				startPoint = this.StartPoint;
			}
			catch
			{
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				this.StartPoint = null;
				throw;
			}
			return startPoint;
		}

		public XYZ PickElbowPoint(XYZ ptStart, string strPrompt = "请确定引线终点：")
		{
			XYZ endPoint;
			try
			{
				this.ThisOperStep = DetailIndexJig.Step.Second;
				this.JigStage = DetailIndexJig.EStage.eEndPt;
				this.StartPoint = ptStart;
				if (this.IfUseCustomerAngle)
				{
					this.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
				}
				else
				{
					this.ResetPoint = XUiJigBase.EResetPoint.eByAxis;
				}
				this.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				this.EndPoint = this.GetResetPoint(this.StartPoint, this.EndPoint);
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				endPoint = this.EndPoint;
			}
			catch
			{
				this.ThisOperStep = DetailIndexJig.Step.Second;
				if (this.m_prompDlg == null || base.CmdEndType != XUiJigBase.ECmdEndType.eEnter)
				{
					this.EndPoint = null;
					this.JigStage = DetailIndexJig.EStage.eNoOper;
					throw;
				}
				base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
				XYZ xyz = base.Client2Revit(this.m_ptCur);
				xyz = this.GetResetPoint(xyz, this.StartPoint);
				double num = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
				XYZ xyz2 = (xyz - this.StartPoint).Normalize();
				this.EndPoint = this.StartPoint + xyz2 * num;
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				endPoint = this.EndPoint;
			}
			return endPoint;
		}

		public XYZ PickEndPoint(XYZ ptStart, string strPrompt = "请确定基线终点：")
		{
			this.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
			this.Angle = 0.0;
			XYZ endPoint;
			try
			{
				this.ThisOperStep = DetailIndexJig.Step.Third;
				this.JigStage = DetailIndexJig.EStage.eEndPt;
				this.StartPoint = ptStart;
				this.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
				this.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				this.EndPoint = this.GetResetPoint(this.StartPoint, this.EndPoint);
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				endPoint = this.EndPoint;
			}
			catch
			{
				this.ThisOperStep = DetailIndexJig.Step.Third;
				if (this.m_prompDlg == null || base.CmdEndType != XUiJigBase.ECmdEndType.eEnter)
				{
					this.EndPoint = null;
					this.JigStage = DetailIndexJig.EStage.eNoOper;
					throw;
				}
				base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
				XYZ xyz = base.Client2Revit(this.m_ptCur);
				double num = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
				XYZ xyz2 = (xyz - this.StartPoint).Normalize();
				this.EndPoint = this.StartPoint + xyz2 * num;
				this.JigStage = DetailIndexJig.EStage.eNoOper;
				endPoint = this.EndPoint;
			}
			return endPoint;
		}

		public XYZ GetResetPoint(XYZ ptBase, XYZ ptUser)
		{
			XYZ result = ptUser;
			if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
			{
				result = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, ptBase, this.Angle);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
			{
				result = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, ptBase);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
			{
				XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, ptBase);
				if (axisPoint != null)
				{
					result = axisPoint;
				}
			}
			return result;
		}

		private bool IfForward(XYZ startpPoint, XYZ endPoint)
		{
			XYZ xyz = endPoint - startpPoint.Normalize();
			return YJKGeometryFuncs.Geometry.LessThan(0.0, xyz.DotProduct(base.Doc.ActiveView.RightDirection));
		}

		private List<XCircle2D> CreateCircle(XYZ startpPoint, XYZ endPoint)
		{
			List<XCircle2D> list = new List<XCircle2D>();
			XYZ xyz = (endPoint - startpPoint).Normalize();
			XYZ point = new XYZ();
			System.Drawing.Point ptCenter = default(System.Drawing.Point);
			if (this.IfForward(startpPoint, endPoint))
			{
				point = endPoint.Add(xyz * DetailIndexJig.m_dCircleRadis);
				ptCenter = base.Revit2Client(point);
			}
			else
			{
				point = endPoint.Add(-xyz * DetailIndexJig.m_dCircleRadis);
				ptCenter = base.Revit2Client(point);
			}
			list.Add(new XCircle2D(ptCenter, (int)(DetailIndexJig.m_dCircleRadis * this.GetScale() * (double)base.Doc.ActiveView.Scale)));
			return list;
		}

		private double GetScale()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			RevitViewExtension.GetRevitWndRectangle(base.UiViewActive, ref num, ref num2, ref num3, ref num4);
			Transform inverse = base.ViewActive.CropBox.Transform.Inverse;
			IList<XYZ> zoomCorners = base.UiViewActive.GetZoomCorners();
			XYZ xyz = inverse.OfPoint(zoomCorners[0]);
			XYZ xyz2 = inverse.OfPoint(zoomCorners[1]);
			return (double)(num4 - num2) / (xyz2.Y - xyz.Y);
		}

		private List<XLine2D> CreateTextBox(XYZ startPoint, XYZ endPoint)
		{
			List<XLine2D> list = new List<XLine2D>();
			XYZ xyz = (startPoint + endPoint) / 2.0;
			XYZ xyz2 = (endPoint - startPoint).Normalize();
			XYZ xyz3 = xyz.Add(base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dOffset * (double)base.Doc.ActiveView.Scale);
			XYZ xyz4 = xyz3.Add(-xyz2 * (DetailIndexJig.m_dTextBoxWidth * (double)base.Doc.ActiveView.Scale / 2.0));
			XYZ xyz5 = xyz3.Add(xyz2 * (DetailIndexJig.m_dTextBoxWidth * (double)base.Doc.ActiveView.Scale / 2.0));
			XYZ point = xyz5.Add(base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dTextBoxHeight * (double)base.Doc.ActiveView.Scale);
			XYZ point2 = xyz4.Add(base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dTextBoxHeight * (double)base.Doc.ActiveView.Scale);
			XLine2D item = new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(xyz5));
			list.Add(item);
			XLine2D item2 = new XLine2D(base.Revit2Client(xyz5), base.Revit2Client(point));
			list.Add(item2);
			XLine2D item3 = new XLine2D(base.Revit2Client(point), base.Revit2Client(point2));
			list.Add(item3);
			XLine2D item4 = new XLine2D(base.Revit2Client(point2), base.Revit2Client(xyz4));
			list.Add(item4);
			XYZ xyz6 = xyz.Add(-base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dOffset * (double)base.Doc.ActiveView.Scale);
			XYZ xyz7 = xyz6.Add(-xyz2 * (DetailIndexJig.m_dTextBoxWidth * (double)base.Doc.ActiveView.Scale / 2.0));
			XYZ xyz8 = xyz6.Add(xyz2 * (DetailIndexJig.m_dTextBoxWidth * (double)base.Doc.ActiveView.Scale / 2.0));
			XYZ point3 = xyz8.Add(-base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dTextBoxHeight * (double)base.Doc.ActiveView.Scale);
			XYZ point4 = xyz7.Add(-base.Doc.ActiveView.UpDirection * DetailIndexJig.m_dTextBoxHeight * (double)base.Doc.ActiveView.Scale);
			XLine2D item5 = new XLine2D(base.Revit2Client(xyz7), base.Revit2Client(xyz8));
			list.Add(item5);
			XLine2D item6 = new XLine2D(base.Revit2Client(xyz8), base.Revit2Client(point3));
			list.Add(item6);
			XLine2D item7 = new XLine2D(base.Revit2Client(point3), base.Revit2Client(point4));
			list.Add(item7);
			XLine2D item8 = new XLine2D(base.Revit2Client(point4), base.Revit2Client(xyz7));
			list.Add(item8);
			return list;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			switch (this.ThisOperStep)
			{
			case DetailIndexJig.Step.First:
				if (this.JigStage == DetailIndexJig.EStage.eOnCurve)
				{
					Graphics graphics = paintEventArgs.Graphics;
					System.Drawing.Point point = base.Revit2Client(this.CenterPoint);
					int distance = XDrawable2D.GetDistance(point, this.m_ptCur);
					XDrawable2D xdrawable2D = new XCircle2D(point, distance);
					XGraphics g = new XGraphics(graphics, base.JigPen);
					xdrawable2D.Draw(g);
					return;
				}
				break;
			case DetailIndexJig.Step.Second:
				if (this.JigStage == DetailIndexJig.EStage.eEndPt)
				{
					XYZ ptUser = base.Client2Revit(this.m_ptCur);
					if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
					{
						XYZ projectPoint = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, this.StartPoint, this.Angle);
						this.m_ptCur = base.Revit2Client(projectPoint);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
					{
						XYZ orthoPoint = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, this.StartPoint);
						this.m_ptCur = base.Revit2Client(orthoPoint);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
					{
						XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, this.StartPoint);
						if (axisPoint != null)
						{
							this.m_ptCur = base.Revit2Client(axisPoint);
							base.DrawAxisLine(paintEventArgs.Graphics, this.StartPoint, axisPoint);
						}
					}
					XGraphics g2 = new XGraphics(paintEventArgs.Graphics, base.JigPen);
					new XLine2D(base.Revit2Client(this.StartPoint), this.m_ptCur).Draw(g2);
					return;
				}
				break;
			case DetailIndexJig.Step.Third:
				if (this.JigStage == DetailIndexJig.EStage.eEndPt)
				{
					XYZ ptUser2 = base.Client2Revit(this.m_ptCur);
					if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
					{
						XYZ projectPoint2 = JigFuncs.GetProjectPoint(base.UiDoc, ptUser2, this.StartPoint, this.Angle);
						this.m_ptCur = base.Revit2Client(projectPoint2);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
					{
						XYZ orthoPoint2 = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser2, this.StartPoint);
						this.m_ptCur = base.Revit2Client(orthoPoint2);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
					{
						XYZ axisPoint2 = JigFuncs.GetAxisPoint(base.UiDoc, ptUser2, this.StartPoint);
						if (axisPoint2 != null)
						{
							this.m_ptCur = base.Revit2Client(axisPoint2);
							base.DrawAxisLine(paintEventArgs.Graphics, this.StartPoint, axisPoint2);
						}
					}
					XGraphics g3 = new XGraphics(paintEventArgs.Graphics, base.JigPen);
					new XLine2D(base.Revit2Client(this.StartPoint), this.m_ptCur).Draw(g3);
					foreach (XLine2D xline2D in this.CreateTextBox(this.StartPoint, base.Client2Revit(this.m_ptCur)))
					{
						xline2D.Draw(g3);
					}
					foreach (XCircle2D xcircle2D in this.CreateCircle(this.StartPoint, base.Client2Revit(this.m_ptCur)))
					{
						xcircle2D.Draw(g3);
					}
				}
				break;
			default:
				return;
			}
		}

		private static double m_dCircleRadis = Common.MMToFeet(5.0);

		private static double m_dOffset = Common.MMToFeet(5.0);

		private static double m_dTextBoxWidth = Common.MMToFeet(20.0);

		private static double m_dTextBoxHeight = Common.MMToFeet(5.0);

		public enum Step
		{
			First,
			Second,
			Third
		}

		public enum EStage
		{
			eNoOper,
			eCenterPt,
			eOnCurve,
			eStartPt,
			eEndPt
		}
	}
}
